package com.ts.api.module.api.convert.plan.http;

import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.log.Log;
import com.gitee.apanlh.util.reflection.CopyUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.ts.api.common.constant.api.ApiBizTypeEnum;
import com.ts.api.module.api.convert.core.entity.ApiApplyParameter;
import com.ts.api.module.api.convert.core.entity.ApiDataExchangeParameter;
import com.ts.api.module.api.convert.core.handler.ApiConvertHandler;
import com.ts.api.module.api.convert.core.http.client.ApiHttpExecutor;
import com.ts.api.module.api.convert.core.http.client.ApiHttpMessage;
import com.ts.api.module.api.convert.core.http.client.ApiHttpRequestConfigure;
import com.ts.api.module.api.convert.plan.context.ApiPlanConvertContext;
import com.ts.api.module.api.entity.ApiUserRequest;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistribute;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributeUserRequest;
import com.ts.api.module.match.plan.model.AbstractPlanMatch;
import com.ts.api.module.product.entity.po.ProductApplyFlowPO;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *  下游计划分发-HTTP处理
 *
 *  @author Pan
 */
@Component
public class ApiPlanHttpHandler {

    @Autowired
    private ApiHttpExecutor apiHttpExecutor;
    @Autowired
    private ApiPlanResponseHandler apiPlanResponseHandler;
    @Autowired
    private ApiPlanConvertContext apiPlanConvertContext;
    @Autowired
    private ApiHttpRequestConfigure apiHttpRequestConfigure;

    /**
     *  发送撞库请求
     *
     *  @param  planDistribute  计划分发对象
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendDataExchange(PlanDistribute planDistribute) {
        ProductPlanPO productPlanPO = planDistribute.getProductPlanPO();
        ProductPO productPO = planDistribute.getProductPO();
        String apiDataExchange = productPO.getApiDataExchange();
        ProductApplyFlowPO currentDistributeFlow = planDistribute.getCurrentDistributeFlow();

        //  创建Http对象
        ApiHttpMessage httpMessage = ApiHttpMessage.create(apiDataExchange, ApiBizTypeEnum.DATA_EXCHANGE);
        try {
            AbstractPlanMatch abstractPlanMatch = planDistribute.getAbstractPlanMatch();

            //  获取分发传输信息
            Integer httpTimeout = abstractPlanMatch.getHttpTimeout();
            PlanDistributeUserRequest planDistributeUserRequest = planDistribute.getPlanDistributeUserRequest();
            String reqId = planDistributeUserRequest.getReqId();

            //  获取请求实体
            ApiConvertHandler apiConvertHandler = apiPlanConvertContext.getPlanHandler(productPO, productPlanPO);
            ApiDataExchangeParameter apiDataExchangeParameter = CopyUtils.copy(planDistributeUserRequest, ApiDataExchangeParameter.class);
            //  原始请求对象
            currentDistributeFlow.setSourceReqData(JsonUtils.toJson(apiDataExchangeParameter));
            Object sendBody = apiConvertHandler.dataExchange(apiDataExchangeParameter);
            //  请求参数装配
            apiHttpRequestConfigure.apiExtendConfigure(httpMessage, apiDataExchangeParameter, sendBody, reqId, httpTimeout - 300);
            httpMessage.setPhoneMd5(apiDataExchangeParameter.getPhoneMd5());

            //  执行HTTP请求
            apiHttpExecutor.execute(httpMessage);
            return httpMessage;
        } catch (Exception e) {
            Log.get().error("{}", e.getMessage(), e);
            httpMessage.setHasSuc(false);
            httpMessage.setExceptionInfo(e);
            currentDistributeFlow.setStackMsg(httpMessage.getStackMsg());
            currentDistributeFlow.setExceptionMsg(httpMessage.getErrorMsg());
            return httpMessage;
        } finally {
            //  设置流程日志信息
            currentDistributeFlow.setCallUrl(apiDataExchange);
            //  解析后请求对象
            currentDistributeFlow.setReqData(String.valueOf(httpMessage.getRequestBody()));
            currentDistributeFlow.setSourceRespData(httpMessage.getResponseBody());
            currentDistributeFlow.setRespData(httpMessage.getResponseBody());
            currentDistributeFlow.setRespCode(String.valueOf(httpMessage.getRespCode()));
        }
    }

    /**
     *  发送撞库请求（h5/app）
     *
     *  @param  httpTimeoutLimit      超时时长（毫秒）
     *  @param  apiUserRequest          发送API消息实体类
     *  @param  productPO            主体信息
     *  @param  productPlanPO        主体计划信息
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendDataExchange(Integer httpTimeoutLimit, ApiUserRequest apiUserRequest, ProductPO productPO, ProductPlanPO productPlanPO) {
        ApiHttpMessage httpMessage = ApiHttpMessage.create(productPO.getApiDataExchange(), ApiBizTypeEnum.DATA_EXCHANGE);
        try {
            String reqId = apiUserRequest.getReqId();

            //  获取请求实体
            ApiConvertHandler apiConvertHandler = apiPlanConvertContext.getPlanHandler(productPO, productPlanPO);
            ApiDataExchangeParameter apiDataExchangeParameter = CopyUtils.copy(apiUserRequest, ApiDataExchangeParameter.class);
            Object sendBody = apiConvertHandler.dataExchange(apiDataExchangeParameter);

            //  请求参数装配
            apiHttpRequestConfigure.apiExtendConfigure(httpMessage, apiDataExchangeParameter, sendBody, reqId, httpTimeoutLimit - 300);
            httpMessage.setPhoneMd5(apiDataExchangeParameter.getPhoneMd5());

            return sendApi(httpMessage, apiConvertHandler, productPO, productPlanPO);
        }  catch (Exception e) {
            Log.get().error("{}", e.getMessage(), e);
            httpMessage.setHasSuc(false);
            httpMessage.setExceptionInfo(e);
            return httpMessage;
        }
    }

    /**
     *  发送API模式撞库请求
     *
     *  @param  apiKeyPO              ApiKey渠道实体
     *  @param  apiUserRequest           发送API消息实体类
     *  @param  productPO             主体信息
     *  @param  productPlanPO         主体计划信息
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendApiDataExchange(ApiKeyPO apiKeyPO, ApiUserRequest apiUserRequest, ProductPO productPO, ProductPlanPO productPlanPO) {
        ApiHttpMessage httpMessage = ApiHttpMessage.create(productPO.getApiDataExchange(), ApiBizTypeEnum.DATA_EXCHANGE);
        try {
            String reqId = apiUserRequest.getReqId();

            //  获取发送请求体
            ApiConvertHandler apiConvertHandler = apiPlanConvertContext.getPlanHandler(productPO, productPlanPO);
            ApiDataExchangeParameter apiDataExchangeParameter = CopyUtils.copy(apiUserRequest, ApiDataExchangeParameter.class);
            Object sendBody = apiConvertHandler.dataExchange(apiDataExchangeParameter);

            //  请求参数装配
            apiHttpRequestConfigure.apiExtendConfigure(httpMessage, apiDataExchangeParameter, sendBody, reqId, apiKeyPO.getApiTimeoutLimit() - 300);
            httpMessage.setPhoneMd5(apiDataExchangeParameter.getPhoneMd5());

            return sendApi(httpMessage, apiConvertHandler, productPO, productPlanPO);
        }  catch (Exception e) {
            Log.get().error("{}", e.getMessage(), e);
            httpMessage.setHasSuc(false);
            httpMessage.setExceptionInfo(e);
            return httpMessage;
        }
    }

    /**
     *  发送进件请求
     *
     *  @param  apiUserRequest          发送API消息实体类
     *  @param  productPO            主体信息
     *  @param  productPlanPO        主体计划信息
     *  @return ApiHttpMessage
     */
    public ApiHttpMessage sendApply(ApiUserRequest apiUserRequest, ProductPO productPO, ProductPlanPO productPlanPO) {
        ApiHttpMessage httpMessage = ApiHttpMessage.create(productPO.getApiApplyUrl(), ApiBizTypeEnum.APPLY);
        try {
            String reqId = apiUserRequest.getReqId();

            //  获取发送请求体
            ApiConvertHandler apiConvertHandler = apiPlanConvertContext.getPlanHandler(productPO, productPlanPO);
            ApiApplyParameter apiApplyParameter = CopyUtils.copy(apiUserRequest, ApiApplyParameter.class);
            Object sendBody = apiConvertHandler.apply(apiApplyParameter);

            //  请求参数装配
            apiHttpRequestConfigure.apiExtendConfigure(httpMessage, apiApplyParameter, sendBody, reqId, 30000);
            httpMessage.setPhoneMd5(apiUserRequest.getPhoneMd5());

            return sendApi(httpMessage, apiConvertHandler, productPO, productPlanPO);
        } catch (Exception e) {
            Log.get().error("{}", e.getMessage(), e);
            httpMessage.setHasSuc(false);
            httpMessage.setExceptionInfo(e);
            return httpMessage;
        }
    }

    /**
     *  发送机构/平台请求-响应业务判断
     *
     *  @param  httpMessage                 http返回消息
     *  @param  apiConvertHandler     机构/平台事件器
     *  @return ApiHttpMessage
     */
    ApiHttpMessage sendApi(ApiHttpMessage httpMessage, ApiConvertHandler apiConvertHandler, ProductPO productPO, ProductPlanPO productPlanPO) throws Exception {
        //  发送API请求
        apiHttpExecutor.execute(httpMessage);
        //  获取业务参数
        ApiBizTypeEnum apiBizTypeEnum = httpMessage.getApiBizTypeEnum();

        String responseBody = httpMessage.getResponseBody();
        //  验证非空情况
        if (ValidParam.isEmpty(responseBody) || ValidParam.isNotEmpty(httpMessage.getErrorMsg()) || httpMessage.hasReqTimeout()) {
            httpMessage.setHasSuc(false);
            return httpMessage;
        }

        //  撞库响应验证
        if (Eq.enums(ApiBizTypeEnum.DATA_EXCHANGE, apiBizTypeEnum)) {
            return apiPlanResponseHandler.respDataExchangeHandle(httpMessage, apiConvertHandler, productPO, productPlanPO);
        }
        //  进件响应验证
        return apiPlanResponseHandler.respApplyHandle(httpMessage, apiConvertHandler, productPO, productPlanPO);
    }
}
